using System.Collections.Generic;
using GameFramework.Battle.Core;
using Gameplay.PVE.Config;
using Gameplay.PVE.Entity;
using Gameplay.PVE.Utils;
using UnityEngine;

namespace Gameplay.PVE.Skill
{
    public class SkillShootMove : SkillBase
    {
        private float startShootTime;
        private float startBulletTime;
        private float shootInterval;
        private float startCastTime;
        private float speed;
        private UnitBase lastLockTarget;
        private Dictionary<int,List<BulletData>> bullets;
        private int bulletCount;
        private Transform tempAimPoint;
        private int shootCount;
        

        protected override void Reset()
        {
            bullets?.Clear();
            bullets = null;
            base.Reset();
        }
        
        protected override void Storage()
        {
            unit.Data.isMoveAttacking = true;
            if (tempAimPoint == null)
            {
                tempAimPoint = new GameObject("tempAimPoint " + unit.Data.id).transform;
                tempAimPoint.transform.SetParent(unit.gameObject.transform);
            }
            unit.Transmit(ETransmitType.Rigid);
            bulletCount = 0;
            
            if (!string.IsNullOrEmpty(config.storage_name))
            {
                unit.Play(config.storage_name);
            }
            

            if (bullets == null)
            {
                bullets = new Dictionary<int, List<BulletData>>();
                for (int i = 0; i < config.bullets.Count; i++)
                {
                    int key = (int) config.bullets[i].z;
                    if (!bullets.ContainsKey(key))
                    {
                        bullets.Add(key,new List<BulletData>());
                    }
                    
                    bullets[key].Add(new BulletData
                    {
                        bulletConfig = config.bullets[i],
                    });
                }
            }

            foreach (var item in bullets.Values)
            {
                for (int i = 0; i < item.Count; i++)
                {
                    item[i].startTime = -1;
                }
            }
            startShootTime = 0;
            stateStartTime = currentTime;
            unit.Data.attackState = 2;
        }

        protected override void Cast()
        {
            stateStartTime = currentTime;
            lastLockTarget = unit.Data.lockTarget;
            shootCount = 0; 
            Shoot();
        }
        
        protected override bool CastEndCondition()
        {
            return false;
        }

        protected override void OnStop()
        {
            unit.Data.aimTransform = null;
            unit.Transmit(ETransmitType.CancelAim);
            unit.Data.isMoveAttacking = false;
            unit.Data.attackState = 0;
            unit.Data.moveState = 0;
            unit.Data.isMoveAttacking = false;
            unit.Data.SetIsInAttack(false);
        }
        
        protected override void Recover()
        {
            OnStop();
            unit.Transmit(ETransmitType.RigidEnd);
            unit.Transmit(ETransmitType.AttackEnd);
            if (!CheckHasAmmo())
            {
                unit.Transmit(ETransmitType.Reload);
            }
        }

        protected override void StartRecover()
        {
            base.StartRecover();
            if (!string.IsNullOrEmpty(config.recover_name))
            {
                unit.Play(config.recover_name);
            }
        }
        
        protected override void CastEvent()
        {
            if (unit.Data.isDead)
            {
                return;
            }
            
            var actionTime = currentTime - startShootTime;
            if (startShootTime != 0 && actionTime >= config.attack_cast_time / unit.Data.attackSpeedRatio)
            {
                if (shootCount >= unit.Data.shootTurns)
                {
                    StartRecover();
                    return;
                }
                else
                {
                    Shoot();
                    startShootTime = currentTime;
                }
            }
            
            
            
            foreach (var item in bullets)
            {
                for (int i = 0; i < item.Value.Count; i++)
                {
                    if (item.Value[i].startTime > 0 && currentTime >= item.Value[i].startTime)
                    {
                        Bullet(item.Value[i].bulletConfig,item.Value[i].effectConfig);
                        item.Value[i].startTime = item.Value[i].startTime + config.attack_cast_time;
                    }
                }
            
            }

            
            unit.Data.SetIsInAttack(!unit.Data.isMoveAttacking);

            if (unit.Data.isGoingToHidePoint)
            {
                StartRecover();
                return;
            }
            
            if (unit.Data.lockTarget == null)
            {
                StartRecover();
                return;
                if (unit.Data.manualAimForward.sqrMagnitude >= 0.001f)
                {
                    unit.Data.SetTargetForward(unit.Data.manualAimForward);
                    //unit.Data.forward = unit.Data.manualAimForward;
                }
            }
            else
            {
                //if (unit.Data.IsAttackInRange())
                {
                    unit.Data.SetTargetForward(unit.Data.lockTarget.Data.position - unit.Data.position);
                }
                /*else
                {
                    StartRecover();
                }*/
            }
        }

        protected virtual void Shoot()
        {
            targetUnit = null;
            if (unit.Data.leftAmmoCount == 0)
            {
                base.StartRecover();
                OnStop();
                unit.Data.aimTransform = null;
                unit.Transmit(ETransmitType.CancelAim);
                return;
            }
            
            
            shootCount++;
            unit.Transmit(ETransmitType.Shoot);

            if (!string.IsNullOrEmpty(config.action_name))
            {
                unit.Play(config.action_name);
            }

            foreach (var item in bullets.Values)
            {
                for (int i = 0; i < item.Count; i++)
                {
                    item[i].startTime = currentTime + item[i].bulletConfig.x / 30f / unit.Data.attackSpeedRatio;
                }
            }
            startShootTime = currentTime;
            
        }

        protected override void UpdateEffect()
        {
            //base.UpdateEffect();
        }

        protected override void UpdateSound(PveSkillConfig config)
        {
            
        }        
        
        private void Bullet(Vector3Int bullet,Vector3 effect)
        {
            if (unit.Data.lockTarget == null)
            {
                return;
            }
            
            if (unit.Data.lockTarget != lastLockTarget)
            {
                if (unit.Data.lockTarget != null && unit.Data.IsAttackInRange(1))
                {
                    lastLockTarget = unit.Data.lockTarget;
                    targetPosition = unit.Data.lockTarget.Data.position;
                    targetForward = targetPosition - unit.Data.position;
                    unit.Data.SetTargetForward(targetForward);
                    unit.Data.forward = targetForward;
                    targetUnit = unit.Data.lockTarget;
                    targetList.Clear();
                    targetList.Add(targetUnit);
                    childSkillTargetList[0] = targetList;
                }
                else
                {
                    targetUnit = null;
                    lastLockTarget = null;
                    StartRecover();
                    return;
                }
                
            }

            
            bulletCount++;
            PlayBulletSound();
            var offset = GetBulletOffset((int)bullet.z);

            //if (config.director_type == 4 || config.director_type == 0)//向targetList方向
            {
                CreateBulletByTargets(offset,(int)bullet.y,0,bullet.z);
            }
            /*else///向自身方向
            {
                CreateBulletByCertainForward(offset,(int)bullet.y,0,index,bullet.z);
            }*/
            if (unit.Data.leftAmmoCount > 0)
            {
                unit.Data.leftAmmoCount--;
            }

            /*var pos = unit.Data.position;
            
            if (effect.y != 0)
            {
                if (unit.Data.gunPoints.Count > effect.x)
                {
                    pos = unit.Data.gunPoints[(int)effect.x].position;
                }
                else
                {
                    pos = unit.Data.gunPoints[0].position;
                }
                PveEffectManager.Instance.PlayEffect((int)effect.y,pos,unit.Data.forward,effect.z / 30f);
            }
            

            ShowBulletCase(pos,bullet.y,bullet.z);*/
        }

    }
}